#pragma once

#include<iostream>

template <class T>
class SharedPtr
{
public:
	SharedPtr(T* ptr = nullptr)
		:_ptr(ptr)
		,_pcount(new int(1))
	{}
	SharedPtr(const SharedPtr& s)
		:_ptr(s._ptr)
		,_pcount(s._pcount)
	{}
	SharedPtr<T>& operator=(const SharedPtr& s)
	{
		if (this != &s)
		{
			if (-- (*(this->_pcount)) == 0)
			{
				delete this->_ptr;
				delete this->_pcount;
			}
			_ptr = s._ptr;
			_pcount = s._pcount;
			(*_pcount)++;
		}
		return *this;
	}
	T& operator* ()
	{
		return *(this->_ptr);
	}
	T* operator& ()
	{
		return this->_ptr;
	}
	~SharedPtr()
	{
		--(*(this->_pcount));
		if (*(this->_pcount) == 0)
		{
			delete _ptr;
			_ptr == nullptr;
			delete _pcount;
			_pcount == nullptr;
		}
	}
private:
	T* _ptr;
	int* _pcount;
};